package com.ruoyi.common.newAdd.utils;

import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
 * @author:wangchao
 */
@Component
public class TimeUtil {
    /**
     * 获取指定某一天的开始时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @param timeZone  如 GMT+8:00
     * @return
     */
    public Long getDailyStartTime(Long timeStamp, String timeZone) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(timeStamp);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当天的开始时间戳
     * @return
     */
    public static long dateOneTime(){
        Long currentTimestamps=System.currentTimeMillis();
        Long oneDayTimestamps= Long.valueOf(60*60*24*1000);
        return currentTimestamps-(currentTimestamps+60*60*8*1000)%oneDayTimestamps;
    }

    /**
     * 获取某天的开始时间戳
     * @return
     */
    public static long getDailyStartTime(long timeStamps){
        Long currentTimestamps=timeStamps;
        Long oneDayTimestamps= Long.valueOf(60*60*24*1000);
        return currentTimestamps-(currentTimestamps+60*60*8*1000)%oneDayTimestamps;
    }

    /**
     * 获取当前时间（时间戳，int类型）
     * @return
     */
    public static int getIntTime(){
        return (int)(TimeUtil.dateOneTime()/1000);
    }

    /**
     * 获取当前时间（字符串类型）
     * @return
     */
    public static String getStringTime(String pattern){
        SimpleDateFormat df = new SimpleDateFormat(pattern);//设置日期格式（原格式为"yyyy-MM-dd HH:mm:ss"）
        System.out.println();// new Date()为获取当前系统时间
        return (df.format(new Date()));
    }

    /**
     * 获取指定某一天的结束时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @param timeZone  如 GMT+8:00
     * @return
     */
    public  Long getDailyEndTime(Long timeStamp, String timeZone) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(timeStamp);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当月开始时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @param timeZone  如 GMT+8:00
     * @return
     */
    public  Long getMonthStartTime(Long timeStamp, String timeZone) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(timeStamp);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }


    /*
    * 获取本周一的开始时间戳
    * */
    public static long getMondayStartTime(){
        Calendar calendar = Calendar.getInstance();
        //设置当前时间戳
        calendar.setTimeInMillis(System.currentTimeMillis());
        //设置时区
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        //设置每周的开始为周一
        int week = calendar.get(calendar.DAY_OF_WEEK);
        if(week == 1){
            //如果是周日加一星期
            week += 7;
        }else{
            //时间向前偏移
            calendar.add(calendar.DATE,2-week);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
        }

        return calendar.getTimeInMillis();

    }

    /*
    * 根据时间戳获取当前为星期几
    * */
    public static Integer getWeek(long timeStamp){
        Calendar calendar = Calendar.getInstance();
        //设置当前时间戳
        calendar.setTimeInMillis(timeStamp);
        //设置时区
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));

        return calendar.get(calendar.DAY_OF_WEEK)-1;
    }

    /**
     * 获取当月的结束时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @param timeZone  如 GMT+8:00
     * @return
     */
    public  Long getMonthEndTime(Long timeStamp, String timeZone) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(timeStamp);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));// 获取当前月最后一天
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当年的开始时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @param timeZone  如 GMT+8:00
     * @return
     */
    public  static Long getYearStartTime(Long timeStamp, String timeZone) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(timeStamp);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.DATE, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当年的最后时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @param timeZone  如 GMT+8:00
     * @return
     */
    public  Long getYearEndTime(Long timeStamp, String timeZone) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(timeStamp);
        int year = calendar.get(Calendar.YEAR);
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTimeInMillis();
    }

    /**
     * 时间戳转字符串
     *
     * @param timestamp 毫秒级时间戳
     * @param zoneId    如 GMT+8或UTC+08:00
     * @return
     */
    public  String timestampToStr(long timestamp, String zoneId) {
        ZoneId timezone = ZoneId.of(zoneId);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), timezone);
        return localDateTime.toString();
    }

//    public static void main(String[] args) {
//        Long currentTime = System.currentTimeMillis();
//        System.out.println("Current Time : " + currentTime + " = " + timestampToStr(currentTime, "GMT+8"));
//        Long dailyStart = getDailyStartTime(currentTime, "GMT+8:00");
//        Long dailyEnd = getDailyEndTime(currentTime, "GMT+8:00");
//        Long monthStart = getMonthStartTime(currentTime, "GMT+8:00");
//        Long monthEnd = getMonthEndTime(currentTime, "GMT+8:00");
//        Long yearStart = getYearStartTime(currentTime, "GMT+8:00");
//        Long yearEnd = getYearEndTime(currentTime, "GMT+8:00");
//
//        System.out.println("Daily Start : " + dailyStart + " = " + timestampToStr(dailyStart, "GMT+8") + " Daily End : " + dailyEnd + " = " + timestampToStr(dailyEnd, "GMT+8"));
//        System.out.println("Month Start : " + monthStart + " = " + timestampToStr(monthStart, "GMT+8") + " Month End : " + monthEnd + " = " + timestampToStr(monthEnd, "GMT+8"));
//        System.out.println("Year Start : " + yearStart + " = " + timestampToStr(yearStart, "GMT+8") + " Year End : " + yearEnd + " = " + timestampToStr(yearEnd, "GMT+8"));
//    }

    /**
     * 13位数时间戳
     * @return
     */
    public static Long time(){
        return System.currentTimeMillis();
    }

    /**
     * 10位数时间戳
     * @return
     */
    public static int getTime(){
        return (int) (System.currentTimeMillis()/1000);
    }


    /**
     * 13位数String时间戳
     * @return
     */
    public static String getTimeStr(){

        return String.valueOf(System.currentTimeMillis());
    }

    public static String getTimeStr10(){

        return String.valueOf(System.currentTimeMillis()/1000);
    }

    /**
     * String(yyyy-MM-dd HH:mm:ss) 转 Date
     *
     * @param time
     * @return
     * @throws ParseException
     */
    // String date = "2010/05/04 12:34:23";
    public static Date StringToDate(String time) throws ParseException {

        Date date = new Date();
        // 注意format的格式要与日期String的格式相匹配
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            date = dateFormat.parse(time);
           // System.out.println(date.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return date;
    }

    /**
     * Date转为String(yyyy-MM-dd HH:mm:ss)
     *
     * @param time
     * @return
     */
    public static String DateToString(Date time) {
        String dateStr = "";
        Date date = new Date();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH/mm/ss");
        try {
            dateStr = dateFormat.format(time);
           // System.out.println(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dateStr;
    }

    /**
     * String(yyyy-MM-dd HH:mm:ss)转化为String(pattern（自定义格式）)
     * @param time
     * @param pattern
     * @return
     */
    public static String stringToString(String time,String pattern) {

        if (time==null){
            return "";
        }
        String dateStr = "";
        Date date = new Date();
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        try {
            dateStr = dateFormat.format(StringToDate(time));
            // System.out.println(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dateStr;
    }

    /**
     * String(yyyy-MM-dd HH:mm:ss)转10位时间戳
     * @param time
     * @return
     */
    public static Integer StringToTimestamp(String time){

        int times = 0;
        try {
            times = (int) ((Timestamp.valueOf(time).getTime())/1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(times==0){
           // System.out.println("String转10位时间戳失败");
        }
        return times;

    }
    /**
     * 10位int型的时间戳转换为String(yyyy-MM-dd HH:mm:ss)
     * @param time
     * @return
     */
    public static String timestampToString(Long time){
        //int转long时，先进行转型再进行计算，否则会是计算结束后在转型
        long temp = (long)time*1000;
        Timestamp ts = new Timestamp(temp);
        String tsStr = "";
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            //方法一
            tsStr = dateFormat.format(ts);
            //System.out.println(tsStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tsStr;
    }

    /**
     * 13位int型的时间戳转换为String(yyyy-MM-dd HH:mm:ss)
     * @param time
     * @return
     */
    public  String timeToString(Long time){
        //int转long时，先进行转型再进行计算，否则会是计算结束后在转型
        Timestamp ts = new Timestamp(time);
        String tsStr = "";
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            //方法一
            tsStr = dateFormat.format(ts);
            //System.out.println(tsStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tsStr;
    }

    /**
     * 13位int型的时间戳转换为String(yyyy-MM-dd HH:mm:ss)
     * @param
     * @return
     */
    public  static String getTimeString(){
        //int转long时，先进行转型再进行计算，否则会是计算结束后在转型
        Timestamp ts = new Timestamp(System.currentTimeMillis());
        String tsStr = "";
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            //方法一
            tsStr = dateFormat.format(ts);
            //System.out.println(tsStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tsStr;
    }

    /**
     * 10位时间戳转Date
     * @param time
     * @return
     */
    public static Date TimestampToDate(Integer time){
        long temp = (long)time*1000;
        Timestamp ts = new Timestamp(temp);
        Date date = new Date();
        try {
            date = ts;
            //System.out.println(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }
    /**
     * Date类型转换为10位时间戳
     * @param time
     * @return
     */
    public  Integer DateToTimestamp(Date time){
        Timestamp ts = new Timestamp(time.getTime());

        return (int) ((ts.getTime())/1000);
    }

    /**
     * long转化为“今天，昨天，前天”时间格式
     * @param aTime
     * @return
     */
    public static String chineseTimeFormat(String aTime){
        //Integer createtime = TimeUtil.StringToTimestamp(aTime+":00");
        long createtime = Long.parseLong(aTime);
        //获取当天时间戳
        Long dateOneTime = dateOneTime();
        //获取当年开始时间戳
        Long yearStartTime = getYearStartTime(System.currentTimeMillis(),"GMT+8:00");

        DateFormat dateFormat = new SimpleDateFormat("HH:mm");
        DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        DateFormat dateFormat2 = new SimpleDateFormat("MM-dd HH:mm");

        String tsStr = "";
        String tsStr1 = "";
        String tsStr2 = "";
        String str;
        try {
            //方法一
            tsStr = dateFormat.format(createtime);
            tsStr1 = dateFormat1.format(createtime);
            tsStr2 = dateFormat2.format(createtime);
            //System.out.println(tsStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(dateOneTime<createtime){
            str = "今天"+tsStr;
        }else if((dateOneTime-createtime) < 24*60*60*1000 && dateOneTime >= createtime){
            str = "昨天"+tsStr;
            //System.out.println(str);
        }else if ((dateOneTime-createtime) >= 24*60*60*1000 && (dateOneTime-createtime) < 2*24*60*60*1000 ){
            str = "前天"+tsStr;
            //System.out.println(str);
        }else if(createtime >= yearStartTime && (dateOneTime-createtime) > 2*24*60*60*1000){
            str = tsStr2;
            //System.out.println(str);
        }else {
            str = tsStr1;
        }

        return str;
    }
    /**
     * long转化为“今天，昨天，前天”时间格式
     * @param aTime
     * @return
     */
    public static String chineseTimeFormat1(String aTime){
        //Integer createtime = TimeUtil.StringToTimestamp(aTime+":00");
        long createtime = Long.parseLong(aTime);
        //获取当天时间戳
        Long dateOneTime = dateOneTime();
        //获取当年开始时间戳
        Long yearStartTime = TimeUtil.getYearStartTime(System.currentTimeMillis(),"GMT+8:00");


        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        String tsStr = dateFormat.format(createtime);


        return tsStr;
    }



    /**********************************************************************************************/


    
//    public static void main(String[] args) throws Exception {
//        String week = "星期二";
//        List<String> test = getWeekly("2020-01-07 14:19:29","2020-01-14 00:00:00",week);
//        System.err.println(test);
//
//    }


    public static boolean weekdayOrNot(String date,String week) throws ParseException{
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date currentDate = sdf.parse(date);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE");
        String currSun = simpleDateFormat.format(currentDate);
        //判断当前是星期几
//        if (currSun.equals(week)) {
//            return true;
//        }
        if (week.contains(currSun)) {
            return true;
        }
        return false;
    }


    public static String getWeek(Date date) throws Exception {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(date);
        String substring = format.substring(0, 7);
        int number = calendar.get(Calendar.WEEK_OF_MONTH);
        String week = substring + "-0" + number;
        return week;
    }

    /**
     * 根据开始时间和结束时间计算之间的星期
     * @param beginDate
     * @param endDate
     * @return
     * @throws Exception
     */
    public static List<String> getWeekly(String beginDate,String endDate,String week) throws Exception{
        //获取俩个日期之间的日期
        List<String> list = findDates(beginDate, endDate);
        List<String> weekDateList = new ArrayList<>();
        //遍历
        for (String date : list) {
            //判断当前是星期几
            boolean thursday = weekdayOrNot(date,week);
            if (thursday==true) {
                weekDateList.add(date);
            }

        }
        return weekDateList;
    }

    public static List<String> findDates(String dBegin, String dEnd) throws ParseException {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(format.parse(dBegin));
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(format.parse(dEnd));
        List<String> Datelist = new ArrayList<String>();
        while (format.parse(dEnd).after(calBegin.getTime())) {
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            Datelist.add(format.format(calBegin.getTime()));
        }
        Datelist.add(dBegin);
        return Datelist;
    }

    /**
     * 日期转星期
     *
     * @param datetime
     * @return
     */
    public static String currentDataToWeek(String datetime) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        // 获得一个日历
        Calendar cal = Calendar.getInstance();
        Date datet = null;
        try {
            datet = f.parse(datetime);
            cal.setTime(datet);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 指示一个星期中的某天。
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }


}
